/*
 * Copyright 2010 Red Hat, Inc. and/or its affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package core.impl.p2;

import core.api.a1.InternalWorkingMemory;
import core.api.a2.InternalFactHandle;
import core.api.a2.PropagationContext;
import core.api.a4.LeftTuple;
import core.api.a4.RightTuple;
import core.impl.p1.DefaultFactHandle;
import core.impl.p1.RuleBasePartitionId;
import core.impl.p4.LeftInputAdapterNode;


public class ModifyPreviousTuples {
    private final DefaultFactHandle.LinkedTuples linkedTuples;

    public ModifyPreviousTuples(InternalFactHandle.LinkedTuples linkedTuples) {
        this.linkedTuples = linkedTuples;
    }
    
    public LeftTuple peekLeftTuple(int partition) {
        return linkedTuples.getFirstLeftTuple(partition);
    }

    public LeftTuple peekLeftTuple(RuleBasePartitionId partitionId) {
        return linkedTuples.getFirstLeftTuple(partitionId);
    }

    public RightTuple peekRightTuple(int partition) {
        return linkedTuples.getFirstRightTuple(partition);
    }

    public RightTuple peekRightTuple(RuleBasePartitionId partitionId) {
        return linkedTuples.getFirstRightTuple(partitionId);
    }

    public void removeLeftTuple(int partition) {
        linkedTuples.removeLeftTuple( peekLeftTuple(partition) );
    }

    public void removeLeftTuple(RuleBasePartitionId partitionId) {
        linkedTuples.removeLeftTuple( peekLeftTuple(partitionId) );
    }

    public void removeRightTuple(int partition) {
        linkedTuples.removeRightTuple( peekRightTuple(partition) );
    }

    public void removeRightTuple(RuleBasePartitionId partitionId) {
        linkedTuples.removeRightTuple( peekRightTuple(partitionId) );
    }

    public void retractTuples(PropagationContext pctx,
                              InternalWorkingMemory wm) {
        linkedTuples.forEachLeftTuple( lt -> doDeleteObject(pctx, wm, lt) );
        linkedTuples.forEachRightTuple( rt -> doRightDelete(pctx, wm, rt) );
    }

    public void doDeleteObject(PropagationContext pctx, InternalWorkingMemory wm, LeftTuple leftTuple) {
        LeftInputAdapterNode liaNode = leftTuple.getTupleSource();
        LeftInputAdapterNode.LiaNodeMemory lm = wm.getNodeMemory( liaNode );
        LeftInputAdapterNode.doDeleteObject(leftTuple, pctx, lm.getSegmentMemory(), wm, liaNode, true, lm);
    }

    public void doRightDelete(PropagationContext pctx, InternalWorkingMemory wm, RightTuple rightTuple) {
        rightTuple.setPropagationContext( pctx );
        rightTuple.retractTuple( pctx, wm );
    }
}
